package com.denlaku.longan.service.impl;

import com.denlaku.longan.datac.SqlReturn;
import com.denlaku.longan.qo.Query;
import com.denlaku.longan.service.CustomApiDataService;
import com.denlaku.longan.service.CustomApiService;
import com.denlaku.longan.service.DataFetchService;
import com.denlaku.longan.service.DataSetService;
import com.denlaku.longan.sql.SelectItem;
import com.denlaku.longan.sql.SqlInfo;
import com.denlaku.longan.util.ForkJoinUtil;
import com.denlaku.longan.util.Lists;
import com.denlaku.longan.vo.CustomApi;
import com.denlaku.longan.vo.CustomApiData;
import com.denlaku.longan.vo.DataSet;
import com.denlaku.longan.vo.DataSetField;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

/**
 * @author tianx
 */
@Service
@Slf4j
public class CustomApiDataServiceImpl implements CustomApiDataService {
    @Autowired
    private CustomApiService customApiInfoService;

    @Autowired
    private DataSetService dataSetService;

    @Autowired
    private DataFetchService dataFetchService;

    @Override
    public CustomApiData fetch(CustomApi apiInfo) {
        Long tenantId = apiInfo.getTenantId();
        Long id = apiInfo.getId();
        CustomApi customApi = customApiInfoService.get(Query.of(tenantId, id));
        Long dataSetId = customApi.getDataSetId();
        DataSet dataSet = dataSetService.get(Query.of(dataSetId));

        SqlInfo info = new SqlInfo();
        info.setDataSet(dataSet);
        info.setTableName(newTableName(dataSet));
        List<DataSetField> fields = dataSet.getFields();
        ListUtils.emptyIfNull(fields).forEach(field -> {
            SelectItem selectItem = newSelectItem(field);
            info.addSelectItem(selectItem);
        });

        SqlReturn query = dataFetchService.query(info);
        List<Map<String, Object>> rows = query.getRows();

        CustomApiData apiData = new CustomApiData();
        apiData.setId(id);
        apiData.setRows(rows);

        return apiData;

    }

    private SelectItem newSelectItem(DataSetField field) {
        SelectItem item = new SelectItem();
        item.setName(field.getName());
        return item;
    }

    private String newTableName(DataSet dataSet) {
        String command = dataSet.getCommand();
        return String.format("(%s) t_mid_165631313", command);
    }

    @Override
    public List<CustomApiData> fetches(List<CustomApi> apiInfoList) {
        int size = apiInfoList.size();
        if (size == 1) {
            CustomApi customApi = apiInfoList.get(0);
            CustomApiData apiData = this.fetch(customApi);
            return Lists.of(apiData);
        }
        try {
            List<Supplier<CustomApiData>> suppliers = Lists.ofSize(size);
            apiInfoList.forEach(apiInfo -> suppliers.add(() -> this.fetch(apiInfo)));
            return ForkJoinUtil.supplyList(suppliers);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return Lists.of();
    }

}
